import java.util.Vector;

import junit.framework.TestCase;
import org.imraniqbal.engine.*;
import org.imraniqbal.pacman.*;

public class GhostTest extends TestCase {
	
	PacmanGame game;
	Map map;
	
	Ghost test1;
	Ghost test2;
	Ghost test3;
	Ghost test4;
	

	public GhostTest(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		super.setUp();
		map = new Map(30,30);
		
		test1 = new Ghost(5,5,1);
		test2 = new Ghost(5,5,2);
		test3 = new Ghost(5,5,3);
		test4 = new Ghost(5,5,4);
		//set lives to -1 (they always respawn)
		test1.setNumOflives(-1);
		test2.setNumOflives(-1);
		test3.setNumOflives(-1);
		test4.setNumOflives(-1);
		
		game = new PacmanGame();
	}

	//MAPPABLE TESTS
	public void testGetSetX() {
		assertEquals(5,test1.getX()); //set to 5 originally
		test1.setX(2);
		assertEquals(2,test1.getX());
	}
	public void testGetSetY() {
		assertEquals(5,test1.getY()); //set to 5 originally
		test1.setY(2);
		assertEquals(2,test1.getY());
	}
	
	//PLAYER TESTS
	public void testSetGetDirection() {
		assertEquals(Direction.LEFT,test1.getDirection()); //default is left
		test1.setDirection(Direction.RIGHT);
		assertEquals(Direction.RIGHT,test1.getDirection());
	}
	public void testSetGetNumLives() {
		assertEquals(-1,test1.getNumOflives()); //default is -1 lives
		test1.setNumOflives(5);
		assertEquals(5,test1.getNumOflives());
	}
	
	public void testUpdateLocationMovable() {
		//check 5,5 for the Player before it moves
		map.addMappable(test1);
		Vector<Mappable> temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
		//attempt to move Player Left, Right, Up, Down
		assertEquals(true,test1.updateLocation(map)); //LEFT
		temp = map.getMappable(4,5);
		assertEquals(true,temp.contains(test1));
		
		test1.setDirection(Direction.RIGHT); 
		assertEquals(true,test1.updateLocation(map)); //RIGHT
		temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
		
		test1.setDirection(Direction.UP); 
		assertEquals(true,test1.updateLocation(map)); //UP
		temp = map.getMappable(5,4);
		assertEquals(true,temp.contains(test1));
		
		test1.setDirection(Direction.DOWN); 
		assertEquals(true,test1.updateLocation(map)); //DOWN
		temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
	}
	public void testUpdateLocationCantMove() {
		//check 5,5 for the Player before it moves
		map.addMappable(test1);
		Vector<Mappable> temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
		//add Walls around player, now it will never move
		map.addWall(4,5);
		map.addWall(6,5);
		map.addWall(5,4);
		map.addWall(5,6);
		//attempt to move Player Left, Right, Up, Down
		assertEquals(false,test1.updateLocation(map)); //LEFT
		temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
		
		test1.setDirection(Direction.RIGHT); 
		assertEquals(false,test1.updateLocation(map)); //RIGHT
		temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
		
		test1.setDirection(Direction.UP); 
		assertEquals(false,test1.updateLocation(map)); //UP
		temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
		
		test1.setDirection(Direction.DOWN); 
		assertEquals(false,test1.updateLocation(map)); //DOWN
		temp = map.getMappable(5,5);
		assertEquals(true,temp.contains(test1));
	}
	
	//GHOST TESTS
	public void testConstructor() {
		Ghost testConstructor = new Ghost(5,5,1);
		assertEquals(5, testConstructor.getX());
		assertEquals(5, testConstructor.getY());
		assertEquals(Direction.LEFT, testConstructor.getDirection());
		assertEquals(1, testConstructor.getNumOflives());
		assertEquals(1, testConstructor.getID());
		
		testConstructor = new Ghost(5, 5, Direction.RIGHT, 3,2);
		assertEquals(5, testConstructor.getX());
		assertEquals(5, testConstructor.getY());
		assertEquals(Direction.RIGHT, testConstructor.getDirection());
		assertEquals(3, testConstructor.getNumOflives());
		assertEquals(2, testConstructor.getID());
	}
	
	public void testSpawnDie() {
		map.addMappable(test1);
		assertEquals(true,map.getMappable(5,5).contains(test1)); //assert that test1 is on the map

		test1.die(map); //die calls spawn() and sets the location to a specific spawn location
		assertEquals(null,map.getMappable(5,5)); //there will be nothing there after it dies... however it will be at 8,5
		test2.die(map);
		test3.die(map);
		test4.die(map);
		assertEquals(true,map.getMappable(8,5).contains(test1)); //assert that test1 is on the map
		assertEquals(true,map.getMappable(9,5).contains(test2)); //assert that test2 is on the map
		assertEquals(true,map.getMappable(10,5).contains(test3)); //assert that test3 is on the map
		assertEquals(true,map.getMappable(11,5).contains(test4)); //assert that test4 is on the map
	}
	
	public void testGetSetID() {
		assertEquals(1,test1.getID()); //test1 ID is set to 1 originally
		test1.setID(3);
		assertEquals(3,test1.getID());
	}
	
	public void testOnEventNoBeastMode() {
		//steps on Pacman, no BeastMode
		Map tempMap = game.getMap();
		tempMap.addMappable(test1);
		Pacman tempPacman = new Pacman(5,5);
		tempMap.addMappable(tempPacman);
		assertEquals(true, tempMap.getMappable(5,5).contains(test1));
		test1.onEvent(new GameEvent(game));
		assertEquals(true, tempMap.getMappable(5,5).contains(test1)); //ghost alive
	}
	public void testOnEventBeastMode() {
		//steps on Pacman, BeastMode on
		Map tempMap = game.getMap();
		tempMap.addMappable(test1);
		Pacman tempPacman = new Pacman(5,5);
		tempPacman.setState(PacmanState.BEASTMODE);
		tempMap.addMappable(tempPacman);
		assertEquals(true, tempMap.getMappable(5,5).contains(test1));
		test1.onEvent(new GameEvent(game));
		assertEquals(false, tempMap.getMappable(5,5).contains(test1)); //no ghost 
		assertEquals(50,game.getScore()); //score should go up by 50 now
	}
	
		//moveGhost() has randomness in it... Not sure how to test it
	
	
	
	
	
	
}













